﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WCS.Infrastructure.Dto.Request.Order
{
    /// <summary>
    /// 支付结果异步通知请求的数据传输对象，包含了易票联支付系统通知商户支付结果所需的所有参数。
    /// </summary>
    public class PaymentResultNotificationRequestDto
    {
        /// <summary>
        /// 商户编号，长度为 32 位的字符串，必传参数。
        /// </summary>
        public string CustomerCode { get; set; }

        /// <summary>
        /// 商户订单号，长度为 32 位的字符串，必传参数，原样复制统一支付请求中的商户订单号。
        /// </summary>
        public string OutTradeNo { get; set; }

        /// <summary>
        /// 易票联订单号，长度为 32 位的字符串，支付结果为成功时必填。
        /// </summary>
        public string? TransactionNo { get; set; }

        /// <summary>
        /// 上游订单号，支付成功时必需，指微信/支付宝/银联返回的订单号。
        /// </summary>
        public string? ChannelOrder { get; set; }

        /// <summary>
        /// 终端号，长度为 20 位的字符串，终端交易时返回。
        /// </summary>
        public string? TerminalNo { get; set; }

        /// <summary>
        /// 终端名称，长度为 100 位的字符串，终端交易时返回。
        /// </summary>
        public string? TerminalName { get; set; }

        /// <summary>
        /// 标签 ID，长度为 14 位的字符串，碰一碰类型交易返回。
        /// </summary>
        public string? NfcTagId { get; set; }

        /// <summary>
        /// 用户在 appId 下的唯一标识，长度为 32 位的字符串，微信类交易需要返回。
        /// </summary>
        public string? OpenId { get; set; }

        /// <summary>
        /// 用户在子商户 appId 下的唯一标识，长度为 32 位的字符串，微信类交易需要返回。
        /// </summary>
        public string? SubOpenId { get; set; }

        /// <summary>
        /// 买家的支付宝唯一用户号，长度为 28 位的字符串，支付宝类交易需要返回，2088 开头的 16 位纯数字。
        /// </summary>
        public string? BuyerId { get; set; }

        /// <summary>
        /// 买家的支付宝账号，长度为 100 位的字符串，支付宝类交易需要返回。
        /// </summary>
        public string? BuyerLogonId { get; set; }

        /// <summary>
        /// 订单金额，单位为分，必传参数。
        /// </summary>
        public long Amount { get; set; }

        /// <summary>
        /// 订单实收金额，单位为分，默认同订单金额，订单实收金额 = 订单金额 - 商户优惠金额，可选参数。
        /// </summary>
        public long? PayerAmount { get; set; }

        /// <summary>
        /// 出资商优惠满减，单位为分，所有 couponDetails 优惠金额之和，可选参数。
        /// </summary>
        public long? TicketAmount { get; set; }

        /// <summary>
        /// 支付结果，长度为 2 位的字符串，必传参数，见附录“支付结果编码”，仅会出现成功和失败的编码。
        /// </summary>
        public string PayState { get; set; }

        /// <summary>
        /// 支付完成时间，格式为 YYYYMMDDHHMMSS，必传参数，该交易达到终态的时间。
        /// </summary>
        public string PayTime { get; set; }

        /// <summary>
        /// 手续费，单位分，支付结果为成功时必填。
        /// </summary>
        public long? ProcedureFee { get; set; }

        /// <summary>
        /// 商户备注，长度为 128 位的字符串，可选参数，原样复制统一支付请求中的 attachData。
        /// </summary>
        public string? AttachData { get; set; }

        /// <summary>
        /// 应结订单金额，单位分，可选参数。
        /// </summary>
        public long? CashAmount { get; set; }

        /// <summary>
        /// 代金券金额，单位分，可选参数。
        /// </summary>
        public long? CouponAmount { get; set; }

        /// <summary>
        /// 支付服务费，单位分，可选参数。
        /// </summary>
        public long? PayServiceCharged { get; set; }

        /// <summary>
        /// 付款人信息，参考 payerInfo，可选参数。
        /// </summary>
        public PayerInfoDto? PayerInfo { get; set; }

        /// <summary>
        /// 优惠信息，银联优惠信息，参考“商品优惠信息”，可选参数。
        /// </summary>
        public object? PromotionDetail { get; set; }

        /// <summary>
        /// 分期信息，JSON 对象，分期支付时必填，参考“分期 IPInfo 对象”。
        /// </summary>
        public object? IpInfo { get; set; }

        /// <summary>
        /// 分期协议版本号，分期必需。
        /// </summary>
        public string? IpProtocolVersion { get; set; }

        /// <summary>
        /// 年化利率计费方式，分期必需，1：单利，2：复利。
        /// </summary>
        public int? IrrType { get; set; }

        /// <summary>
        /// 签约折算年化利率，分期必需，详见年化内部收益率（IRR）计算公式，百分比数字，保留两位小数，示例：15.18%年化率取值：15.18。
        /// </summary>
        public float? Irr { get; set; }

        /// <summary>
        /// 门店编号，长度为 32 位的字符串，可选参数。
        /// </summary>
        public string? StoreId { get; set; }

        /// <summary>
        /// 门店名称，长度为 512 位的字符串，可选参数。
        /// </summary>
        public string? StoreName { get; set; }

        /// <summary>
        /// 交易说明，长度为 100 位的字符串，可选参数。
        /// </summary>
        public string? Remark { get; set; }

        /// <summary>
        /// 保留信息，长度为 400 位的字符串，参考“reserved 字段说明”，可选参数。
        /// </summary>
        public string? Reserved { get; set; }

        /// <summary>
        /// 优惠信息，使用优惠券时必须，参考 couponDetails 说明。
        /// </summary>
        public object? CouponDetails { get; set; }

        /// <summary>
        /// 随机字符串，长度为 32 位的字符串，必传参数，推荐随机数生成算法产生。
        /// </summary>
        public string NonceStr { get; set; }
    }

    /// <summary>
    /// 付款人信息 DTO
    /// </summary>
    public class PayerInfoDto
    {
        /// <summary>
        /// 借贷记，可选参数，D：借记，C：贷记，S：借贷合一
        /// </summary>
        public string? CardType { get; set; }

        /// <summary>
        /// 资金渠道，可选参数
        /// </summary>
        public string? FundChannel { get; set; }

        /// <summary>
        /// 银行码，可选参数
        /// </summary>
        public string? BankCode { get; set; }

        /// <summary>
        /// 付款账号，可选参数
        /// </summary>
        public string? CardNo { get; set; }

        /// <summary>
        /// 支付人姓名，长度为 32 位的字符串，可选参数
        /// </summary>
        public string? PayerName { get; set; }

        /// <summary>
        /// 限成年人付款，微信支付时有效，可选参数，ADULT：限制用户只有是成年人才能支付
        /// </summary>
        public string? LimitPayer { get; set; }
    }

    /// <summary>
    /// 支付结果通知响应的 DTO，包含返回码和返回信息。
    /// </summary>
    public class PaymentResultNotificationResponseDto
    {
        /// <summary>
        /// 返回码，长度为 4 位的字符串，必传参数，0000：成功，0001：失败。
        /// </summary>
        public string ReturnCode { get; set; }

        /// <summary>
        /// 返回信息，长度为 128 位的字符串，可选参数，响应返回参数 0000 表示处理成功，其他表示处理失败，处理失败的系统会继续通知。
        /// </summary>
        public string? ReturnMsg { get; set; }
    }
}
